#
# LsL/SessionAudit.pm
#
# Copyright (C) 2004 Albacore Technology LLC, Inc. All Rights Reserved
#
# $Id: Group.pm 14 2005-05-23 23:32:07Z bill $
#

package LsL::SessionAudit;

use strict;
use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK $EVENT_TYPES $EVENT_TYPE_LABELS );
use Exporter;

#
# public (exported) variables
#
$VERSION   = 0.01;
@ISA       = qw(Exporter);
@EXPORT    = qw( );
@EXPORT_OK = qw();

$EVENT_TYPES =
[qw(
  LOGIN
  LOGOUT
  SU
  SUEXIT
  CROSSCHECK
  TIMEOUT
  ADDUSER
  BILLINGPRE
  BILLINGPOST
)];

$EVENT_TYPE_LABELS =
{
  'LOGIN'       => 'Login',
  'LOGOUT'      => 'Logout',
  'SU'          => 'Switch user',
  'SUEXIT'      => 'Switch user exit',
  'CROSSCHECK'  => 'Session key cross check validation failure',
  'TIMEOUT'     => 'Session time out',
  'ADDUSER'     => 'Add new user',
  'BILLINGPRE'  => 'Billing Script (pre SPA)',
  'BILLINGPOST' => 'Billing Script (post SPA)',
};

#
# private (non-exported) variables
#

#
# Encapsulated class data
#
my %_attr_data = (
  'attrs' => {
    'userid'        => '',
    'ccode'         => '',
    'lname'         => '',
    'fname'         => '',
    'username'      => '',
    'event_type'    => '',
    'end_date'      => '',
    'start_date'    => '',
    'modify_userid' => '',
    'modify_ccode'  => '',
    'modify_lname'  => '',
    'modify_fname'  => '',
    'modify_uname'  => '',
  },
  # 0 -> arg, 1 -> arg hash
  'process_attrs' => sub {
      my ($args) = @_;
  },
);

#
# Class methods, to operate on encapsulated class data
#

# Classwide default value for a specified object attribute
sub _set_attr {
  my ($args, $attr) = @_;
  # set default
  $args->{$attr} = $_attr_data{'attrs'}{$attr} unless exists $args->{$attr};
}

# Classwide attribute processing
sub _process_attr {
  my ($args) = @_;
  $_attr_data{'process_attrs'}->($args) if exists $_attr_data{'process_attrs'};
}

# List of names of all specified object attributes
sub _standard_keys {
  keys %{$_attr_data{'attrs'}};
}

#
# public class methods
#

#
# class instance methods
#
sub new {
  my ( $class, $sobj ) = @_;

  _set_attr($sobj,$_) foreach ( _standard_keys() );

  _process_attr($sobj);

  my $where = '0 = 0';
  my @args;

  if ($sobj->{'event_type'}) {
    $where .= ' and event_type = ?';
    push @args, $sobj->{'event_type'};
  }

  if ($sobj->{'ccode'}) {
    $where .= ' and ccode = ?';
    push @args, $sobj->{'ccode'};
  }

  #if ($sobj->{'start_date'} && $sobj->{'end_date'}) {
  #  $where .= q{ and event_time >= to_date(?,'YYYY-MM-DD') and event_time <= to_date(?,'YYYY-MM-DD') + 1};
  #  push @args, $sobj->{'start_date'}, $sobj->{'end_date'};
  #}

  if ($sobj->{'userid'}) {
    $where .= ' and userid = ?';
    push @args, $sobj->{'userid'};
  }

  if ($sobj->{'lname'}) {
    $where .= " and upper(lname) like ? escape '\\'";
    push @args, uc($sobj->{'lname'}) . '%';
  }

  if ($sobj->{'fname'}) {
    $where .= " and upper(fname) like ? escape '\\'";
    push @args, uc($sobj->{'fname'}) . '%';
  }

  if ($sobj->{'username'}) {
    $where .= " and upper(username) like ? escape '\\'";
    push @args, uc($sobj->{'username'}) . '%';
  }

  if ($sobj->{'modify_userid'}) {
    $where .= ' and modify_userid = ?';
    push @args, $sobj->{'modify_userid'};
  }

  if ($sobj->{'modify_ccode'}) {
    $where .= ' and modify_ccode = ?';
    push @args, $sobj->{'modify_ccode'};
  }

  # create the object
  my $self = {
      'sobj'            => $sobj,
      'where'           => $where,
      'args'            => \@args,
  };

  bless ( $self, $class );

  return( $self );
}

sub count {
  my ($self) = @_;

  my $sql = qq
  {
    select
      count(*)
    from
      audit_sessions
    where
      $self->{'where'}
  };

  my $dbi = LsL::DB::sdbi();
  my $sth;

  $sth = $dbi->db_prep($sql);
  $dbi->db_exec($sth, @{$self->{'args'}});
  my @d = $dbi->db_fetch($sth);
  $dbi->db_done($sth);

  return $d[0] || 0;
}

sub results {
  my ($self,$start,$count) = @_;

  $start = $start || '0';
  $count = $count ||  100;

  my $sql = qq
  {
    select
      userid,
      ccode,
      lname,
      fname,
      username,
      event_type,
      time,
      event_time,
      modify_userid,
      modify_ccode,
      modify_lname,
      modify_fname,
      modify_username
    from
      audit_sessions
    where
      $self->{'where'}
    order by
      event_time desc
  };

  my $dbi = LsL::DB::sdbi();
  my $sth;

  $sth = $dbi->db_prep($sql);
  $dbi->db_exec($sth, @{$self->{'args'}});

  my $items;
  while(my @d = $dbi->db_fetch($sth)) {
    my $out_h;

    @$out_h{'userid','ccode','lname','fname','username','event_type','time','event_time','modify_userid','modify_ccode','modify_lname','modify_fname','modify_uname', 'rownum'} = map {((defined $_)?$_:'')} @d[ 0,1,2,3,4,5,6,7,8,9,10,11,12,13];

    push @{$items}, $out_h;
  }
  $dbi->db_done($sth);

  return ($items?$items:[]);
}

1;
